#include "notification.h"
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusPendingCall>
#include <QDebug>
#include <QSettings>
#include <QGSettings>
#include <QDBusReply>
#include <QFileInfo>
#include <QDir>
#include <QProcess>
#include <unistd.h>

#define PROMPT_TIMOEOUT -1

notification::notification(QWidget *parent)
{
    prompt_timer = new QTimer(this);
    connect(prompt_timer, SIGNAL(timeout()), this, SLOT(promptTimeout()));

    if (!prompt_timer->isActive()) {
        qDebug()<<"Activation Prompt Timeout:"<<PROMPT_TIMOEOUT*2<<"s";
        prompt_timer->start((PROMPT_TIMOEOUT*2)*1000);
    }

    check_notification();
}


void notification::check_notification()
{
    QByteArray ba;
    QString current_active;
    bool check_state = false;
    bool isCloudPlatform = false;

    QSettings settings("/usr/share/kylin-activation/activation_conf.ini", QSettings::IniFormat);
    QString cvd = settings.value("MODE_Activation/cloud_virtual_desktop").toString();

    if ("true"==cvd) {
        qDebug()<<"Cloud Desktop Activation Mode ...";
        isCloudPlatform = true;
    } else {
        qDebug()<<"Non cloud desktop activation mode ...";
        isCloudPlatform = false;
    }

    if (isCloudPlatform) {
        QString config_path = QDir::homePath() + "/.config/activation_conf.ini";
        QFileInfo file(config_path);

        if (!file.exists()) {
            qDebug() << "activation_conf.ini isn't exist.";
            exit(0);
        }

        QSettings settings(config_path, QSettings::IniFormat);
        ba = settings.value("Active_State/current_active").toByteArray();
        current_active =QString::fromLatin1( QByteArray::fromBase64(ba));
        if (current_active=="true") {
            check_state = true;
            qDebug() << "Current active state: true";
        } else if (current_active=="false") {
            qDebug() << "Current active state: false";
            check_state = false;
        } else {
            qDebug() << "Activation status not obtained ...";
        }
        sleep(28);//等待云桌面激活结束
    } else {
        check_state = false;
        // sleep(5);//弹窗bug，增加延迟避免login界面弹出
    }

    if((!check_state)&&(QGSettings::isSchemaInstalled(QString("org.ukui.activation").toLocal8Bit()))) {

        QGSettings gsetting(QString("org.ukui.activation").toLocal8Bit());
        bool activation_prompt = gsetting.get("activation-prompt").toBool();
        qDebug() << "activation_prompt: "<<activation_prompt;

        bool activationState = checkActivationState();
        qDebug() << "activationState: "<<activationState;

        if(activation_prompt && 0==activationState) {
            QDBusInterface iface("org.freedesktop.Notifications",
                                 "/org/freedesktop/Notifications",
                                 "org.freedesktop.Notifications",
                                 QDBusConnection::sessionBus());

            QDBusConnection::sessionBus().connect("org.freedesktop.Notifications",
                                            "/org/freedesktop/Notifications",
                                            "org.freedesktop.Notifications",
                                            "ActionInvoked", this,
                                            SLOT(onActionInvoked(quint32, QString))
            );

            QDBusConnection::sessionBus().connect("org.freedesktop.Notifications",
                                            "/org/freedesktop/Notifications",
                                            "org.freedesktop.Notifications",
                                            "NotificationClosed", this,
                                            SLOT(onNotificationClosed(quint32, quint32))
            );

            QList<QVariant> args;
            QStringList actions;//action字段
            actions << "default" << "The current system is not activated, please activate the system first!";
            actions << "action_key1" << QObject::tr("No longer prompt") << "action_key2" << QObject::tr("Activate now");

            QVariantMap hints;
            hints.insert("urgency", 1);//紧急程度，可选填

            QStringList actionState;//x-ukui-action-state字段
            actionState << "disable" << "enable" << "enable";//default action设置为disable的话会屏蔽用户点击通知窗体和窗体URL跳转
            hints.insert("x-ukui-action-state", actionState);

            args<<QObject::tr("System activation")
                <<((unsigned int) 0)
                <<QString("kylin-activation")
                <<QString("") //summary: QObject::tr("System activation")
                <<QObject::tr("The current system is not activated, please activate the system first!")
                <<actions
                <<hints
                <<PROMPT_TIMOEOUT;

            QDBusReply<quint32> messageId = iface.callWithArgumentList(QDBus::AutoDetect,"Notify",args);
            this->messageId = messageId.value();
            qDebug() << "messageId: " << this->messageId;
        } else {
            qDebug() << "should exit.";
            exit(0);
        }

    } else {
        qDebug() << "should exit.";
        exit(0);
    }
}

void notification::promptTimeout()
{
    qDebug() << "prompt timeout, should quit.";
    exit(0);
}

void notification::onActionInvoked(quint32 id, QString actionKey)
{
    //TODO 根据actionKey选择不同自定义逻辑行为
    if (id == this->messageId) {

        qDebug() << "onActionInvoked: " << id << actionKey;
        QProcess p(0);
        QString cmd = "";

        if (actionKey == "action_key1") { //No longer prompt
            cmd = "gsettings set org.ukui.activation activation-prompt false";
        } else if (actionKey == "action_key2" || actionKey == "default") { //Activate now
            int ret=checkOsRelease();
            if(ret==1) {
                qDebug() << "ukui-control-center -m About";
                cmd = "ukui-control-center -m About";
            } else {
                qDebug() << "ukui-control-center --about";
                cmd = "ukui-control-center --about";
            }
        }

        p.startDetached(cmd);

    } else {
        qDebug() << "I don't know whose ID it is: " << id;
    }

    qDebug() << "should exit.";
    exit(0);
}

void notification::onNotificationClosed(quint32 id, quint32 reason)
{
    qDebug() << "==notificationClosed==" << id << reason;

    qDebug() << "should quit .";
    exit(0);
}

int notification::checkActivationState()
{
    int ret=0;

    QDBusMessage m = QDBusMessage::createMethodCall("org.freedesktop.activation",
                                                    "/org/freedesktop/activation",
                                                    "org.freedesktop.activation.interface",
                                                    "status");

     QDBusMessage response = QDBusConnection::systemBus().call(m);
     if (response.type() == QDBusMessage::ReplyMessage) {
         ret=response.arguments().takeFirst().toInt();
         if(ret==0) {//判断是否过期
             m=QDBusMessage::createMethodCall("org.freedesktop.activation",
                                              "/org/freedesktop/activation",
                                              "org.freedesktop.activation.interface",
                                              "date");
             response = QDBusConnection::systemBus().call(m);
             if(response.type() == QDBusMessage::ReplyMessage) {
                 if(!response.arguments().takeFirst().toString().isEmpty())//技术服务过期
                     return 1;
             }
         }
     }
    return ret;
}

int notification::checkOsRelease()
{
    //获取/etc/os-release的PRETTY_NAME
    char* prettyName=NULL;
    char *path = "/etc/os-release";
    char buf[256] = {0};
    int ret=-1;
    FILE *fp = fopen(path, "r");
    if (NULL != fp)
    {
        while (NULL != fgets(buf, 256, fp))
        {
            if (strlen(buf) > 11)
            {
                if (0 == strncmp(buf, "PRETTY_NAME", 11))
                {
                    long int start=(long int)strchr(buf,'"');//第一次出现"的地址
                    long int end=(long int)strrchr(buf,'"');//最后一次出现"的地址
                    int len=end-start-1;//两个"之间的字符个数
                    prettyName=(char *)malloc(sizeof(char) * (len+1));
                    strncpy(prettyName,strchr(buf,'"')+1,len);
                    prettyName[len]='\0';
                    break;
                }
            }
        }
        fclose(fp);
    }

    if (0 == strncmp(prettyName, "Kylin V10 SP1", 12) ||
                         0 == strcmp(prettyName, "Kylin V10 Professional") ||
                          0 == strcmp(prettyName, "Kylin V10.1"))
        ret=1;
    else if(0 == strncmp(prettyName,"Kylin V10 SP2",12))
        ret=2;
    else
        ret=0;
    return ret;
}
